from flask_cors import CORS
from models import db, Category, Product, Cart, CartItem, User, OrderItem
from datetime import datetime
from database import init_db, init_test_data

from flask import Flask, render_template, request, redirect, url_for, flash, session, jsonify
from flask_login import LoginManager, login_user, logout_user, login_required, current_user
from werkzeug.security import generate_password_hash, check_password_hash
import os


# 初始化Flask应用
app = Flask(__name__)
# 数据库配置（SQLite，文件存储在项目根目录）
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///shopping.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # 关闭不必要的警告

# 初始化登录管理
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))


# 跨域配置（开发环境允许所有来源，生产环境需限制域名）
CORS(app, resources={r"/api/*": {"origins": "*"}})

# -------------------------- 1. 分类API --------------------------
@app.route('/api/categories', methods=['GET'])
def get_categories():
    """获取所有商品分类"""
    categories = Category.query.all()
    result = [{"id": c.id, "name": c.name, "slug": c.slug} for c in categories]
    return jsonify(result), 200


# -------------------------- 2. 商品API --------------------------
@app.route('/api/products', methods=['GET'])
def get_products():
    """获取商品列表（支持分页、分类筛选、搜索、排序）"""
    # 1. 获取请求参数
    page = request.args.get('page', 1, type=int)  # 页码（默认1）
    per_page = request.args.get('per_page', 8, type=int)  # 每页数量（默认8）
    category_id = request.args.get('category', type=int)  # 分类筛选（可选）
    search = request.args.get('search', '')  # 搜索关键词（可选）
    sort = request.args.get('sort', 'default')  # 排序方式（default/price-asc/price-desc/rating）

    # 2. 构建查询条件
    query = Product.query
    # 分类筛选
    if category_id:
        query = query.filter(Product.category_id == category_id)
    # 搜索（匹配商品名称或描述）
    if search:
        query = query.filter(
            (Product.name.ilike(f'%{search}%')) | (Product.description.ilike(f'%{search}%'))
        )
    # 排序
    if sort == 'price-asc':
        query = query.order_by(Product.price.asc())  # 价格升序
    elif sort == 'price-desc':
        query = query.order_by(Product.price.desc())  # 价格降序
    elif sort == 'rating':
        query = query.order_by(Product.rating.desc())  # 评分降序
    else:
        query = query.order_by(Product.create_time.desc())  # 默认：最新上架

    # 3. 分页查询
    pagination = query.paginate(page=page, per_page=per_page, error_out=False)
    products = pagination.items

    # 4. 构造响应数据（含库存状态）
    result = {
        "products": [
            {
                "id": p.id,
                "name": p.name,
                "description": p.description,
                "price": p.price,
                "stock": p.stock,  # 库存数量（前端需展示）
                "image_url": p.image_url,
                "rating": p.rating,
                "review_count": p.review_count,
                "category_id": p.category_id,
                "category_name": p.category.name  # 分类名称（前端展示用）
            } for p in products
        ],
        "total": pagination.total,  # 商品总数
        "pages": pagination.pages,  # 总页数
        "current_page": page,       # 当前页码
        "per_page": per_page        # 每页数量
    }
    return jsonify(result), 200


@app.route('/api/products/<int:product_id>', methods=['GET'])
def get_product_detail(product_id):
    """获取单个商品详情（含库存）"""
    product = Product.query.get_or_404(product_id)
    result = {
        "id": product.id,
        "name": product.name,
        "description": product.description,
        "price": product.price,
        "stock": product.stock,  # 核心：库存信息
        "image_url": product.image_url,
        "rating": product.rating,
        "review_count": product.review_count,
        "category_id": product.category_id,
        "category_name": product.category.name
    }
    return jsonify(result), 200


# -------------------------- 3. 购物车API --------------------------
def get_or_create_cart(session_id):
    """获取或创建购物车（按session_id）"""
    cart = Cart.query.filter_by(session_id=session_id).first()
    if not cart:
        cart = Cart(session_id=session_id)
        db.session.add(cart)
        db.session.commit()
    return cart


@app.route('/api/cart', methods=['GET'])
def get_cart():
    """获取购物车（需传session_id）"""
    session_id = request.args.get('session_id')
    if not session_id:
        return jsonify({"error": "session_id不能为空"}), 400

    cart = get_or_create_cart(session_id)
    # 计算购物车总价和总数量
    total_price = sum(item.quantity * item.product.price for item in cart.items)
    total_items = sum(item.quantity for item in cart.items)

    # 构造购物车数据（含商品库存校验）
    cart_items = [
        {
            "id": item.id,
            "product_id": item.product_id,
            "product": {
                "id": item.product.id,
                "name": item.product.name,
                "price": item.product.price,
                "image_url": item.product.image_url,
                "stock": item.product.stock  # 实时库存（避免超卖）
            },
            "quantity": item.quantity,
            "subtotal": item.quantity * item.product.price  # 小计
        } for item in cart.items
    ]

    return jsonify({
        "cart_id": cart.id,
        "items": cart_items,
        "total_items": total_items,
        "total_price": round(total_price, 2)
    }), 200


@app.route('/api/cart/items', methods=['POST'])
def add_cart_item():
    """添加商品到购物车（含库存校验）"""
    data = request.get_json()
    session_id = data.get('session_id')
    product_id = data.get('product_id')
    quantity = data.get('quantity', 1)

    # 1. 参数校验
    if not all([session_id, product_id, quantity > 0]):
        return jsonify({"error": "参数错误（session_id、product_id必填，数量>0）"}), 400

    # 2. 库存校验
    product = Product.query.get_or_404(product_id)
    if product.stock < quantity:
        return jsonify({"error": f"库存不足！当前库存：{product.stock}"}), 400

    # 3. 添加到购物车（重复商品则更新数量）
    cart = get_or_create_cart(session_id)
    cart_item = CartItem.query.filter_by(cart_id=cart.id, product_id=product_id).first()

    if cart_item:
        # 检查更新后数量是否超过库存
        new_quantity = cart_item.quantity + quantity
        if new_quantity > product.stock:
            return jsonify({"error": f"库存不足！当前库存：{product.stock}，购物车已有：{cart_item.quantity}"}), 400
        cart_item.quantity = new_quantity
    else:
        cart_item = CartItem(cart_id=cart.id, product_id=product_id, quantity=quantity)
        db.session.add(cart_item)

    db.session.commit()
    # 返回更新后的购物车
    return get_cart()  # 复用get_cart接口的逻辑


@app.route('/api/cart/items/<int:item_id>', methods=['PUT'])
def update_cart_item(item_id):
    """修改购物车商品数量（含库存校验）"""
    data = request.get_json()
    session_id = request.args.get('session_id')
    new_quantity = data.get('quantity', 1)

    if not all([session_id, new_quantity > 0]):
        return jsonify({"error": "参数错误（session_id必填，数量>0）"}), 400

    # 1. 查找购物车项
    cart = get_or_create_cart(session_id)
    cart_item = CartItem.query.filter_by(id=item_id, cart_id=cart.id).first_or_404()

    # 2. 库存校验
    if cart_item.product.stock < new_quantity:
        return jsonify({"error": f"库存不足！当前库存：{cart_item.product.stock}"}), 400

    # 3. 更新数量
    cart_item.quantity = new_quantity
    db.session.commit()
    return get_cart()


@app.route('/api/cart/items/<int:item_id>', methods=['DELETE'])
def delete_cart_item(item_id):
    """删除购物车商品"""
    session_id = request.args.get('session_id')
    if not session_id:
        return jsonify({"error": "session_id不能为空"}), 400

    cart = get_or_create_cart(session_id)
    cart_item = CartItem.query.filter_by(id=item_id, cart_id=cart.id).first_or_404()

    db.session.delete(cart_item)
    db.session.commit()
    return get_cart()

# ========== 用户系统（简化版） ==========
@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        if User.query.filter_by(username=username).first():
            flash('❌ 用户名已存在')
        else:
            hashed_pw = generate_password_hash(password)
            new_user = User(username=username, password=hashed_pw)
            db.session.add(new_user)
            db.session.commit()
            flash('✅ 注册成功，请登录')
            return redirect(url_for('login'))
    return render_template('register.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        user = User.query.filter_by(username=username).first()
        if user and check_password_hash(user.password, password):
            login_user(user)
            flash('✅ 登录成功')
            return redirect(url_for('index'))
        else:
            flash('❌ 用户名或密码错误')
    return render_template('login.html')

@app.route('/logout')
def logout():
    logout_user()
    session.pop('cart', None)
    flash('👋 已登出')
    return redirect(url_for('index'))

@app.route('/')
def index():
    return render_template('index.html')

# -------------------------- 启动程序 --------------------------
if __name__ == '__main__':
    os.makedirs('instance', exist_ok=True)
    os.makedirs('static/uploads', exist_ok=True)
    # 首次运行时初始化测试数据（后续注释掉，避免重复清空）
    # init_test_data(app)
    
    # 启动服务（host=0.0.0.0允许局域网访问，port=5000）
    app.run(host='127.0.0.1', port=8000, debug=True)